package com.ibeeking.gmc.job.admin.controller;

import com.ibeeking.gmc.job.admin.controller.annotation.PermissionLimit;
import com.ibeeking.gmc.job.admin.core.conf.XxlJobAdminConfig;
import com.ibeeking.gmc.job.core.biz.AdminBiz;
import com.ibeeking.gmc.job.core.biz.model.*;
import com.ibeeking.gmc.job.core.util.GsonTool;
import com.ibeeking.gmc.job.core.util.XxlJobRemotingUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * Created by xuxueli on 17/5/10.
 */
@Controller
@RequestMapping("/api")
public class JobApiController {

    @Resource
    private AdminBiz adminBiz;

    /**
     * api
     *
     * @param uri
     * @param data
     * @return
     */
    @RequestMapping("/{uri}")
    @ResponseBody
    @PermissionLimit(limit = false)
    public ReturnT<String> api(HttpServletRequest request, @PathVariable("uri") String uri, @RequestBody(required = false) String data) {

        // valid
        if (!"POST".equalsIgnoreCase(request.getMethod())) {
            return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, HttpMethod not support.");
        }
        if (uri == null || uri.trim().length() == 0) {
            return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, uri-mapping empty.");
        }
        if (!tokenCheck(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "The access token is wrong.");
        }

        // services mapping
        if ("callback".equals(uri)) {
            List<HandleCallbackParam> callbackParamList = GsonTool.fromJson(data, List.class, HandleCallbackParam.class);
            return adminBiz.callback(callbackParamList);
        } else if ("registry".equals(uri)) {
            RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class);
            return adminBiz.registry(registryParam);
        } else if ("registryRemove".equals(uri)) {
            RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class);
            return adminBiz.registryRemove(registryParam);
        } else {
            return new ReturnT<>(ReturnT.FAIL_CODE, "invalid request, uri-mapping(" + uri + ") not found.");
        }

    }

    /**
     * 创建任务
     *
     * @param request
     * @param jobInfoParam
     * @return
     */
    @RequestMapping("/createJob")
    @ResponseBody
    @PermissionLimit(limit = false)
    public ReturnT<String> createJob(HttpServletRequest request, @RequestBody JobInfoParam jobInfoParam) {
        if (!tokenCheck(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "The access token is wrong.");
        }
        return adminBiz.createJob(jobInfoParam);
    }

    /**
     * 修改任务
     *
     * @param request
     * @param jobInfoParam
     * @return
     */
    @RequestMapping("/modifyJob")
    @ResponseBody
    @PermissionLimit(limit = false)
    public ReturnT<String> modifyJob(HttpServletRequest request, @RequestBody JobInfoParam jobInfoParam) {
        if (!tokenCheck(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "The access token is wrong.");
        }
        return adminBiz.modifyJob(jobInfoParam);
    }

    /**
     * 启动/停止任务
     *
     * @param request
     * @param param
     * @return
     */
    @RequestMapping("/startStopJob")
    @ResponseBody
    @PermissionLimit(limit = false)
    public ReturnT<String> startStopJob(HttpServletRequest request, @RequestBody JobStartStopParam param) {
        if (!tokenCheck(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "The access token is wrong.");
        }
        return adminBiz.startStopJob(param);
    }

    /**
     * 删除任务
     *
     * @param request
     * @param param
     * @return
     */
    @RequestMapping("/delJob")
    @ResponseBody
    @PermissionLimit(limit = false)
    public ReturnT<String> delJob(HttpServletRequest request, @RequestBody BaseJobParam param) {
        if (!tokenCheck(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "The access token is wrong.");
        }
        return adminBiz.delJob(param);
    }

    /**
     * 立即执行一次
     *
     * @param request
     * @param param
     * @return
     */
    @RequestMapping("/executeOnceJob")
    @ResponseBody
    @PermissionLimit(limit = false)
    public ReturnT<String> executeOnceJob(HttpServletRequest request, @RequestBody BaseJobParam param) {
        if (!tokenCheck(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "The access token is wrong.");
        }
        return adminBiz.executeOnceJob(param);
    }

    /**
     * 下次执行时间
     *
     * @param request
     * @param param
     * @return
     */
    @RequestMapping("/nextJobTime")
    @ResponseBody
    @PermissionLimit(limit = false)
    public ReturnT<String> nextJobTime(HttpServletRequest request, @RequestBody BaseJobParam param) {
        if (!tokenCheck(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "The access token is wrong.");
        }
        return adminBiz.nextJobTime(param);
    }

    private Boolean tokenCheck(String accessToken) {
        if (StringUtils.isNotBlank(XxlJobAdminConfig.getAdminConfig().getAccessToken())
                && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(accessToken)) {
            return false;
        }
        return true;
    }
}
